package cn.ococci.dm.Network;

/**
 * Created by cyan on 15/12/29.
 */

import com.alibaba.fastjson.Json;
import com.alibaba.fastjson.JsonObject;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.apache.http.Header;

import cn.ococci.dm.Base.BaseApp;
import cn.ococci.dm.Base.BaseController;
import cn.ococci.dm.Main.Const;
import cn.ococci.dm.Main.Tools.LogTool;
import cn.ococci.dm.Main.Tools.StringTool;
import cn.ococci.dm.Main.Tools.ThreadTool;
import cn.ococci.dm.Main.Tools.ToastTool;
import cn.ococci.dm.Main.View.WebProgress;


/**
 * Created by cyan on 15/9/21.
 * <p/>
 * 网络业务逻辑处理
 * 这里的网络请求是在android-Async_http中进行的封装可根据自己的需求进行修改)
 */
public class Http extends AsyncHttpResponseHandler {

    private static final String TAG = "Http";

    public final int STATUS_CREATE = 0;
    public final int STATUS_DOWN = 1;
    public final int STATUS_CANCELED = 2;
    public final int STATUS_FAILURE = 3;
    public final int STATUS_CACHED = 4;

    private BaseController bc;
    private AsyncHttpClient client;
    private RequestParams p;  //请求参数
    private String url;
    private boolean isBack;

    private String loadingStr;
    private int timeout;
    private int status;

    public Http() {
        this.isBack = true;
    }


    public Http(BaseController bc) {
        this.bc = bc;
        this.isBack = false;
    }

    public Http(int timeout) {
        this.isBack = true;
        this.timeout = timeout * 1000;
    }

    /**
     * 设置超时时间
     * @param timeout
     * @return
     */
    public Http setTimeout(int timeout) {
        this.timeout = timeout * 1000;
        return this;
    }


    /**
     * 前台请求变成后台请求
     * @return
     */
    public Http turnToBack(){
        isBack = true;
        return this;
    }

    /**
     * 返回是否显示对话框
     * @return
     */
    public boolean showProgress() {
        return !isBack;
    }

    /**
     * 返回此次请求是否是后台请求
     * @return
     */
    public boolean isBack() {
        return isBack;
    }

    private static void prepare(String url, RequestParams p, Http http) {
        if(http.showProgress()){
            WebProgress.createDialog(http.bc.getBaseActivity(), http);
            if(http.loadingStr != null){
                WebProgress.setLoadingStr(http.loadingStr);
            }
        }
        http.url = url;
        http.p = p;
        if (http.timeout != 0) {
            http.client.setTimeout(http.timeout); //设置超时时间
        }
    }

    public static Http get(String url, RequestParams p, Http http) {
        AsyncHttpClient client = new AsyncHttpClient();
        http.client = client;
        prepare(url, p, http);
        url = Urls.base + url;
        client.get(url, p, http);
        return http;
    }

    public static Http post(String url, RequestParams p, Http http){
        AsyncHttpClient client = new AsyncHttpClient();
        http.client = client;
        prepare(url, p, http);
        url = Urls.base + url;
        client.post(url, p, http);
        return http;
    }

    public static Http put(String url, RequestParams p, Http http){
        AsyncHttpClient client = new AsyncHttpClient();
        http.client = client;
        prepare(url, p, http);
        url = Urls.base + url;
        client.put(url, p, http);
        return http;
    }


    /**
     * 成功返回数据
     * @param json
     */
    public void onSuccess(JsonObject json) {

    }

    /**
     * 任何请求失败都必须经过这个方法
     * @param msg
     * @param code
     */
    public void onFailure(int code,String msg) {

    }

    /**
     * 一般是网络错误,或者是服务器返回的网络错误码
     */
    private void webFailure(int code,String msg){
        if(code == 0 && showProgress()){
            ToastTool.showShortTime("请保持网络畅通");
        }
        onFailure(code,msg);
    }


    /**
     * 网络请求正确返回,业务逻辑有其它错误
     * @param code
     * @param msg
     */
    private void bizFailure(int code, String msg) {
        LogTool.error(TAG, "出现业务错误，代码为:" + code + " 出错信息为:" + msg);
//        if (showProgress()) {
//            ToastTool.showShortTime(msg);
//        }
        onFailure(code, msg);
    }

    public void onCancel() {
        this.onFailure(-1, "cancel");
    }

    public synchronized void cancel() {
        if (status == STATUS_CREATE) {
            status = STATUS_CANCELED;
            LogTool.log(TAG, "请求被取消，地址为:" + url);
            if (client != null)
                client.cancelRequests(BaseApp.getInstance(),true);
            this.onCancel();
        }
    }


    @SuppressWarnings("deprecation")
    @Override
    public synchronized void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
        if (showProgress()) {
            WebProgress.webDismiss();
        }
        LogTool.log(TAG, "网络操作成功返回,url: " + url);
        if (status == STATUS_CANCELED) {
            LogTool.error(TAG, "数据已经返回，但是请求已经被取消");
            return;
        }
        if (status != STATUS_CACHED)
            status = STATUS_DOWN;

        LogTool.log(TAG,"statusCode:" + statusCode);
        if (statusCode == 200) {
            String json = new String(responseBody);

            if (StringTool.isEmpty(json)){
                onFailure(502,"无数据返回");
                return;
            }

            LogTool.log(TAG,"从服务器上获取到的数据是:"+json);
            final JsonObject jsonObj = Json.parseObject(json);
            if(hasSuccess(jsonObj)){
                if (isBack()) {
                    ThreadTool.runOnNewThread(new Runnable() {
                        @Override
                        public void run() {
                            onSuccess(jsonObj);
                        }
                    });
                } else{
                    onSuccess(jsonObj);
                }
            }else { //由于这里的返回参数 errorCode 可能不存在

                if (jsonObj.containsKey(Const.BuilderParams.errCode)){

                    bizFailure(retValueErrorCode(jsonObj),"业务逻辑错误");

                }else {

                    bizFailure(502,"业务逻辑错误");

                }
            }


        }else{
            LogTool.log(TAG,"请求成功之后返回的码有问题:"+statusCode);
            this.webFailure(statusCode, "出现网络错误");
        }
    }


    @Override
    public synchronized void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
        if (showProgress()) {
            WebProgress.webDismiss();
        }
        if (status == STATUS_CANCELED) {
            LogTool.error(TAG, "数据已经返回，但是请求已经被取消");
            return;
        }
        status = STATUS_FAILURE;
        LogTool.error(TAG, "出现网络错误,状态码是:" + statusCode + " 网络请求地址是:" + url, error);
        this.webFailure(statusCode, "出现网络错误");
    }


    /**
     *  请求结果是否成功
     * @param json
     * @return
     */
    public static boolean hasSuccess(JsonObject json){
        return json.getBoolean(Const.REQUEST_RETURN_VALUE);
    }



    /**
     *  请求结果返回码
     * @param json
     * @return
     */
    public static int retValueErrorCode(JsonObject json){
        return json.getIntValue(Const.BuilderParams.errCode);
    }




}
